#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import socket,argparse,sys,requests,os,atexit
from urllib.parse import urlparse
from multiprocessing.dummy import  Pool as ThreadPool
"""
only check CVE-2020-2551 vuls
Twitter: @Hktalent3135773
Creator: 51pwn_com
Site: https://51pwn.com
How use:
python3 CVE-2020-2551.py -u http://192.168.26.79:7001
# 32 Thread check
cat allXXurl.txt|grep -Eo 'http[s]?:\/\/[^ \/]+'|sort -u|python3 CVE-2020-2551.py -e
cat ../T3.txt rst/T3.txt|sort -u -r|py3 ~/mytools/CVE-2020-2551/CVE-2020-2551.py -e
cat ../T3.txt rst/*.txt gy/*.txt|sort -u -r|py3 ~/mytools/CVE-2020-2551/CVE-2020-2551.py -e
"""
g_f = None

bDebug=False
g_oNRpt={}
def log(e):
    if bDebug:
        print(e)
def doThreads(fnCbk,lists,nThreads=64):
    pool = ThreadPool(nThreads)
    pool.map(fnCbk,lists)
    pool.close()
    pool.join()

def checkOnline(url,cbkUrl):
    try:
        requests.post('http://51pwn.com/CVE-2020-2551/',data={'url':url,cbkUrl:cbkUrl},timeout=(5,9))
    except Exception as e:
        log(e)
        pass

def doSendOne(ip,port,data):
    sock=None
    res=None
    s=ip+':'+str(port)
    try:
        if 0 == len(ip) or s in g_oNRpt:
            return
        g_oNRpt[s]='1'
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(7)
        server_addr = (ip, int(port))
        sock.connect(server_addr)
        sock.send(data)
        res = sock.recv(10)
        if b'GIOP' in res:
            #checkOnline(ip+':'+str(port),'http://yourSite/?target={}&rst={}')
            return True
    except Exception as e:
        log(s)
        log(e)
        pass
    finally:
        if sock!=None:
            sock.close()
    return False
g_bPipe=False
def doOne(url):
    global g_bPipe,g_f
    if not 'http' in url:
        url='http://'+url
    oH=urlparse(url)
    a=oH.netloc.split(':')
    port=80
    if 2 == len(a):
        port=a[1]
    elif 'https' in oH.scheme:
        port=443
    if doSendOne(a[0],port,bytes.fromhex('47494f50010200030000001700000002000000000000000b4e616d6553657276696365')):
        print('found CVE-2020-2551 ', oH.netloc)
        g_f.write(oH.netloc + "\n")
        g_f.flush()
    elif g_bPipe == False:
        print('not found CVE-2020-2551 ', oH.netloc)

def doPipe():
    global g_bPipe
    g_bPipe=True
    buff = ''
    a=[]
    while True:
        buff = sys.stdin.readline()
        if not buff:
            break 
        if buff.endswith('\n'):
            szTmpCmd = buff[:-1]
            szTmpCmd=szTmpCmd.rstrip()
        buff = ''
        if not szTmpCmd:
            break
        a.append(szTmpCmd)
    doThreads(doOne,a)

def exit_handler():
    global g_f
    g_f.close()
atexit.register(exit_handler)
szFileOn = os.path.dirname(os.path.abspath(__file__))+  "/CVE-2020-2551.txt"
if __name__=='__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("-u","--url",help="http://xxx.xxx.xxx:7001/")
    parser.add_argument("-e","--pipeCheck",help="pipe check is Ok,thread 32",action="store_true")
    parser.add_argument("-o","--out",help="out file name",default="CVE-2020-2551.txt")
    args = parser.parse_args()
    if args.out:
        szFileOn=args.out
    g_f = open(szFileOn,"a+")

    if args.url:
        doOne(args.url)
    if args.pipeCheck:
        doPipe()